﻿#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//11.求成员变量相对于结构体开头的偏移量所需库；
#include <stddef.h>

struct PersonPointer
{
	int a;
	char b;
	char buf[64];
	int d;
};
//1.指针步长：指针变量+1，要向后跳多少字节，是由该指针的类型char或int决定，char跳1个字节，int跳4个；
//6.指针的类型，不单单决定指针的步长，还决定解引用的时候从给定地址开始，取该类型大小的字节数；
void testPointerStep()
{
	char* pC = NULL;
	printf("2.char*类型的指针变量pC的初始位置为：%d\n", pC);//0
	printf("3.char*类型的指针变量pC+1的位置为：%d\n", pC + 1);//1
	printf("---------------------------------------------------------------\n");

	int* pI = NULL;
	printf("4.int*类型的指针变量pI的初始位置为：%d\n", pI);//0
	printf("5.int*类型的指针变量pI+1的位置为：%d\n", pI + 1);//4
	printf("---------------------------------------------------------------\n");

	char buf[1024] = { 0 };
	int a = 100;
	//7.往buf数组中拷贝，一个int类型的值100，此时拷贝从buf[1]开始拷贝；
	memcpy(buf + 1, &a, sizeof(int));
	char* pb = buf;
	//9.由于pb是char*变量，步长为1个字节，*(pb+1)只能取到一个字节，就是buf[1]。现在转成int*变量，就能取4个字节了，
		//即buf[1],buf[2],buf[3],buf[4]。
	printf("8.使用指针*(int*)(pb+1)取出来值为：%d\n", *(int*)(pb + 1));//100

	struct PersonPointer pp = { 10,'a',"hello world!",100 };
	char b;
	//11.char变量b之前，是int变量a，是4个字节；
	printf("10.成员char类型变量b在结构体pp中，相对于开头的字节偏移量为：%d\n", offsetof(struct PersonPointer, b));//4
	//13.和上面9的解释一样，offsetof()求出变量d相对于开头的字节偏移量，就是变量d的地址；先获取到结构体pp的地址，再
		//转成char*变量，此时就能通过&pp+偏移量，得到变量d的值。但是d的值为int类型，需要转成int*类型才能获取到。
	printf("12.通过指针获取到变量d的值为：%d\n", *(int*)((char*)&pp + offsetof(struct PersonPointer, d)));//100
}

//main188：指针的步长
int main188()
{
	testPointerStep();

	system("pause");
	return EXIT_SUCCESS;
}